export class Intersection {
    // 判断是否相交
    static isIntersect(p0: cc.Vec2, p1: cc.Vec2, p2: cc.Vec2, p3: cc.Vec2): boolean {
        let res: boolean = false;
        function ccw(a: cc.Vec2, b: cc.Vec2, c: cc.Vec2) {
            let v1, v2, v;
            a = cc.v2(a);
            b = cc.v2(b);
            c = cc.v2(c);
            v1 = b.sub(a);
            v2 = c.sub(a);
            v = v1.cross(v2);
            return v;
        }
        if (ccw(p0, p1, p2) * ccw(p0, p1, p3) < 0
            && ccw(p2, p3, p0) * ccw(p2, p3, p1) < 0
        ) {
            res = true;
        }
        return res;
    }
    // 获取线段与线段的交点
    static lineLine(p0: cc.Vec2, p1: cc.Vec2, p2: cc.Vec2, p3: cc.Vec2): cc.Vec2 {
        let res: cc.Vec2 = cc.v2();
        let x1 = p0.x,
            y1 = p0.y,
            x2 = p1.x,
            y2 = p1.y,
            x3 = p2.x,
            y3 = p2.y,
            x4 = p3.x,
            y4 = p3.y;
        // // 由点斜式 y - y0 = k * (x - x0) 可得看k1 k2
        // let k1 = (y2 - y1) / (x2 - x1),
        //     k2 = (y4 - y3) / (x4 - x3);

        res.x = ((x2 - x1) * (x3 - x4) * (y3 - y1) - x3 * (x2 - x1) * (y3 - y4) + x1 * (y2 - y1) * (x3 - x4)) / ((y2 - y1) * (x3 - x4) - (x2 - x1) * (y3 - y4));
        res.y = ((y2 - y1) * (y3 - y4) * (x3 - x1) - y3 * (y2 - y1) * (x3 - x4) + y1 * (x2 - x1) * (y3 - y4)) / ((x2 - x1) * (y3 - y4) - (y2 - y1) * (x3 - x4));

        return res;
    }
    // 线与多边形的交点
    static linePolygon(p0, p1, polygonPoints: cc.Vec2[]): cc.Vec2[] {
        let p2, p3, resArr: cc.Vec2[] = [];
        if (polygonPoints.length > 2) {
            // let ctx = GameHelper.getDebugSceneCtx();
            // ctx.clear();
            for (let i = 0; i < polygonPoints.length; i++) {
                p2 = polygonPoints[i];
                p3 = i == polygonPoints.length - 1 ? polygonPoints[0] : polygonPoints[i + 1];
                // ctx.strokeColor = cc.color(255, 0, 0);
                // ctx.moveTo(p0.x, p0.y);
                // ctx.lineTo(p1.x, p1.y);
                // ctx.stroke();
                if (Intersection.isIntersect(p0, p1, p2, p3)) {
                    let res = Intersection.lineLine(p0, p1, p2, p3);
                    resArr.push(res);
                    // ctx.strokeColor = cc.color(255, 255, 0);
                    // ctx.moveTo(p2.x, p2.y);
                    // ctx.lineTo(p3.x, p3.y);
                    // ctx.stroke();
                    // ctx.strokeColor = cc.color(255, 255, 0);
                    // ctx.circle(res.x, res.y, 10);
                    // ctx.stroke();
                }
            }
        } else {
            console.error('点数太少构不成多边形')
        }
        // debugger
        return resArr;
    }
    // 判断一个点是否在三角形内
    static _testInTriangle(point, triA, triB, triC) {
        let AB = triB.sub(triA), AC = triC.sub(triA), BC = triC.sub(triB), AD = point.sub(triA), BD = point.sub(triB);
        return (AB.cross(AC) >= 0 !== AB.cross(AD) < 0)  // D,C 在AB同同方向
            && (AB.cross(AC) >= 0 !== AC.cross(AD) >= 0) // D,B 在AC同同方向
            && (BC.cross(AB) > 0 !== BC.cross(BD) >= 0); // D,A 在BC同同方向
    }
    // 点是否在多边形内
    static pointInPolygon(point: cc.Vec2, polygon: Array<cc.Vec2>) {
        var inside = false;
        var x = point.x;
        var y = point.y;

        // use some raycasting to test hits
        // https://github.com/substack/point-in-polygon/blob/master/index.js
        var length = polygon.length;

        for (var i = 0, j = length - 1; i < length; j = i++) {
            var xi = polygon[i].x, yi = polygon[i].y,
                xj = polygon[j].x, yj = polygon[j].y,
                intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);

            if (intersect) inside = !inside;
        }

        return inside;
    }
}
